package com.wjm.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {
    public static void main(String[] args) {
        System.out.println("反射示例");
        test0();
    }

    /**
     * 如何拿一个类的字节码文件呢
     */
    private static void test0() {
        Person p=new Person();
        Class  aClass = p.getClass();

        Person p1=new Person();
        Class  aClass1 = p1.getClass();
        System.out.println(aClass == aClass1);


        Class aClass2 = Person.class;
        Class aClass3 = Person.class;
        System.out.println(aClass2==aClass3);

        try {
            Class  aClass4 = Class.forName("com.wjm.reflection.Person");
            Class aClass5 = Class.forName("com.wjm.reflection.Person");
            System.out.println(aClass4==aClass5);

            //创建对象
            Object obj = aClass4.newInstance();//Person中必须有空参构建函数，否则会抛出InstantiationException异常

            //拿到构造函数
            Constructor constructor5 = aClass5.getConstructor(int.class, String.class);//与类的参数类型顺序要一致
            Object obj5 = constructor5.newInstance(30, "a");//与类的参数类型顺序要一致


            //拿私有字段，并设置值并获取新值
            Field age5 = aClass5.getDeclaredField("age");//获取私有字段
            age5.setAccessible(true);//设置可访问私有属性
            age5.set(obj5,89);//为私有age设置值
            Object age5value = age5.get(obj5);//获取私有age的最新值
            System.out.println(age5value);


            //获取所有方法，获取私有方法
            Class  aClass6 = Class.forName("com.wjm.reflection.Person");
            Method[] methods6 = aClass6.getMethods();//所有共有方法
            Method[] declaredMethods6 = aClass6.getDeclaredMethods();//所有方法包含私有
            for(Method methodTemp6:declaredMethods6){
                System.out.println(methodTemp6);
//                private void com.wjm.reflection.Person.method()
//                public void com.wjm.reflection.Person.show()
            }


            //调用空参数方法
            Class  aClass7 = Class.forName("com.wjm.reflection.Person");
            Method methods7 = aClass7.getMethod("show",null);//获取空参数一般方法
            Object obj7 = aClass7.newInstance();
            methods7.invoke(obj7,null);//show

            //调用有参方法
            Class  aClass8 = Class.forName("com.wjm.reflection.Person");
            Method methods8 = aClass8.getMethod("parmMethod",String.class,int.class);//获取空参数一般方法
            Object obj8 = aClass8.newInstance();
            methods8.invoke(obj8,"aaa",90);//str:aaa	num:90


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

    }
}
